home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / xampp-win32-1.6.5-installer.exe / php / PEAR / SOAP / Base.php next >
Encoding:
PHP Script  |  2007-12-20  |  41.6 KB  |  1,264 lines

  1. <?php
  2. /**
  3.  * This file loads all required libraries, defines constants used across the
  4.  * SOAP package, and defines the base classes that most other classes of this
  5.  * package extend.
  6.  *
  7.  * PHP versions 4 and 5
  8.  *
  9.  * LICENSE: This source file is subject to version 2.02 of the PHP license,
  10.  * that is bundled with this package in the file LICENSE, and is available at
  11.  * through the world-wide-web at http://www.php.net/license/2_02.txt.  If you
  12.  * did not receive a copy of the PHP license and are unable to obtain it
  13.  * through the world-wide-web, please send a note to license@php.net so we can
  14.  * mail you a copy immediately.
  15.  *
  16.  * @category   Web Services
  17.  * @package    SOAP
  18.  * @author     Dietrich Ayala <dietrich@ganx4.com> Original Author
  19.  * @author     Shane Caraveo <Shane@Caraveo.com>   Port to PEAR and more
  20.  * @author     Chuck Hagenbuch <chuck@horde.org>   Maintenance
  21.  * @author     Jan Schneider <jan@horde.org>       Maintenance
  22.  * @copyright  2003-2005 The PHP Group
  23.  * @license    http://www.php.net/license/2_02.txt  PHP License 2.02
  24.  * @link       http://pear.php.net/package/SOAP
  25.  */
  26.  
  27. /**
  28.  * SOAP_OBJECT_STRUCT makes PEAR::SOAP use objects for SOAP structures rather
  29.  * than arrays.  This has been done to provide a closer match to php-soap.  If
  30.  * the old behaviour is needed, set to false.  The old behaviour is
  31.  * deprecated.
  32.  *
  33.  * @global bool $GLOBALS['SOAP_OBJECT_STRUCT']
  34.  */
  35. $GLOBALS['SOAP_OBJECT_STRUCT'] = true;
  36.  
  37. /**
  38.  * SOAP_RAW_CONVERT makes PEAR::SOAP attempt to determine what SOAP type a PHP
  39.  * string COULD be.  This may result in slightly better interoperability when
  40.  * you are not using WSDL, and are being lazy and not using SOAP_Value to
  41.  * define types for your values.
  42.  *
  43.  * @global bool $GLOBALS['SOAP_RAW_CONVERT']
  44.  */
  45. $GLOBALS['SOAP_RAW_CONVERT'] = false;
  46.  
  47. require_once 'PEAR.php';
  48. require_once 'SOAP/Type/dateTime.php';
  49. require_once 'SOAP/Type/hexBinary.php';
  50.  
  51. // optional features
  52. $GLOBALS['SOAP_options'] = array();
  53.  
  54. @include_once 'Mail/mimePart.php';
  55. @include_once 'Mail/mimeDecode.php';
  56. if (class_exists('Mail_mimePart')) {
  57.     $GLOBALS['SOAP_options']['Mime'] = 1;
  58.     define('MAIL_MIMEPART_CRLF', "\r\n");
  59. }
  60.  
  61. @include_once 'Net/DIME.php';
  62. if (class_exists('Net_DIME_Message')) {
  63.     $GLOBALS['SOAP_options']['DIME'] = 1;
  64. }
  65.  
  66. /**
  67.  * Enable debugging information?
  68.  *
  69.  * @global bool $GLOBALS['SOAP_DEBUG']
  70.  * @name $SOAP_DEBUG
  71.  */
  72. $GLOBALS['SOAP_DEBUG'] = false;
  73.  
  74. if (!function_exists('version_compare') ||
  75.     version_compare(phpversion(), '4.1', '<')) {
  76.     die("requires PHP 4.1 or higher\n");
  77. }
  78. if (version_compare(phpversion(), '4.1', '>=') &&
  79.     version_compare(phpversion(), '4.2', '<')) {
  80.     define('FLOAT', 'double');
  81. } else {
  82.     define('FLOAT', 'float');
  83. }
  84.  
  85. if (!defined('INF')) {
  86.     define('INF', 1.8e307);
  87. }
  88. if (!defined('NAN')) {
  89.     define('NAN', 0.0);
  90. }
  91.  
  92. define('SOAP_LIBRARY_VERSION', '0.10.1');
  93. define('SOAP_LIBRARY_NAME',    'PEAR-SOAP 0.10.1-beta');
  94.  
  95. // Set schema version.
  96. define('SOAP_XML_SCHEMA_VERSION',  'http://www.w3.org/2001/XMLSchema');
  97. define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance');
  98. define('SOAP_XML_SCHEMA_1999',     'http://www.w3.org/1999/XMLSchema');
  99. define('SOAP_SCHEMA',              'http://schemas.xmlsoap.org/wsdl/soap/');
  100. define('SOAP_SCHEMA_ENCODING',     'http://schemas.xmlsoap.org/soap/encoding/');
  101. define('SOAP_ENVELOP',             'http://schemas.xmlsoap.org/soap/envelope/');
  102.  
  103. define('SCHEMA_DISCO',             'http://schemas.xmlsoap.org/disco/');
  104. define('SCHEMA_DISCO_SCL',         'http://schemas.xmlsoap.org/disco/scl/');
  105.  
  106. define('SCHEMA_SOAP',              'http://schemas.xmlsoap.org/wsdl/soap/');
  107. define('SCHEMA_SOAP12',            'http://schemas.xmlsoap.org/wsdl/soap12/');
  108. define('SCHEMA_SOAP_HTTP',         'http://schemas.xmlsoap.org/soap/http');
  109. define('SCHEMA_WSDL_HTTP',         'http://schemas.xmlsoap.org/wsdl/http/');
  110. define('SCHEMA_MIME',              'http://schemas.xmlsoap.org/wsdl/mime/');
  111. define('SCHEMA_WSDL',              'http://schemas.xmlsoap.org/wsdl/');
  112. define('SCHEMA_DIME',              'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/');
  113. define('SCHEMA_CONTENT',           'http://schemas.xmlsoap.org/ws/2002/04/content-type/');
  114. define('SCHEMA_REF',               'http://schemas.xmlsoap.org/ws/2002/04/reference/');
  115.  
  116. define('SOAP_DEFAULT_ENCODING',  'UTF-8');
  117.  
  118. class SOAP_Base_Object extends PEAR
  119. {
  120.     /**
  121.      * Store debugging information in $_debug_data?
  122.      *
  123.      * @see $debug_data, SOAP_Base
  124.      * @var boolean $_debug_flag
  125.      */
  126.     var $_debug_flag = false;
  127.  
  128.     /**
  129.      * String containing debugging information if $_debug_flag is true.
  130.      *
  131.      * @access public
  132.      * @see $debug_flag, SOAP_Base
  133.      * @var string $_debug_data
  134.      */
  135.     var $_debug_data = '';
  136.  
  137.     /**
  138.      * Supported encodings, limited by XML extension.
  139.      *
  140.      * @var array $_encodings
  141.      */
  142.     var $_encodings = array('ISO-8859-1', 'US-ASCII', 'UTF-8');
  143.  
  144.     /**
  145.      * Fault code.
  146.      *
  147.      * @var string $_myfaultcode
  148.      */
  149.     var $_myfaultcode = '';
  150.  
  151.     /**
  152.      * Recent PEAR_Error object.
  153.      *
  154.      * @var PEAR_Error $fault
  155.      */
  156.     var $fault = null;
  157.  
  158.     /**
  159.      * Constructor.
  160.      *
  161.      * @see $debug_data, _debug()
  162.      *
  163.      * @param string $faultcode  Error code.
  164.      */
  165.     function SOAP_Base_Object($faultcode = 'Client')
  166.     {
  167.         $this->_myfaultcode = $faultcode;
  168.         $this->_debug_flag = $GLOBALS['SOAP_DEBUG'];
  169.         parent::PEAR('SOAP_Fault');
  170.     }
  171.  
  172.     /**
  173.      * Raises a SOAP error.
  174.      *
  175.      * Please refer to the SOAP definition for an impression of what a certain
  176.      * parameter stands for.
  177.      *
  178.      * Use $debug_flag to store errors to the member variable $debug_data
  179.      *
  180.      * @see $debug_flag, $debug_data, SOAP_Fault
  181.      *
  182.      * @param string|object $str  Error message or object.
  183.      * @param string $detail      Detailed error message.
  184.      * @param string $actorURI
  185.      * @param mixed $code
  186.      * @param mixed $mode
  187.      * @param mixed $options
  188.      * @param boolean $skipmsg
  189.      */
  190.     function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null,
  191.                               $mode = null, $options = null, $skipmsg = false)
  192.     {
  193.         // Pass through previous faults.
  194.         $is_instance = isset($this) && is_a($this, 'SOAP_Base_Object');
  195.         if (is_object($str)) {
  196.             $fault =& $str;
  197.         } else {
  198.             if (!$code) {
  199.                 $code = $is_instance ? $this->_myfaultcode : 'Client';
  200.             }
  201.             $fault =& new SOAP_Fault($str,
  202.                                      $code,
  203.                                      $actorURI,
  204.                                      $detail,
  205.                                      $mode,
  206.                                      $options);
  207.         }
  208.         if ($is_instance) {
  209.             $this->fault =& $fault;
  210.         }
  211.  
  212.         return $fault;
  213.     }
  214.  
  215.     function _isfault()
  216.     {
  217.         return $this->fault != null;
  218.     }
  219.  
  220.     function &_getfault()
  221.     {
  222.         return $this->fault;
  223.     }
  224.  
  225.     /**
  226.      * Adds a string to the debug data.
  227.      *
  228.      * @param string $string  Debugging message.
  229.      */
  230.     function _debug($string)
  231.     {
  232.         if ($this->_debug_flag) {
  233.             $this->_debug_data .= get_class($this) . ': ' .
  234.                 str_replace('>', ">\r\n", $string) . "\n";
  235.         }
  236.     }
  237.  
  238. }
  239.  
  240. /**
  241.  * Common base class of all SOAP classes.
  242.  *
  243.  * @access   public
  244.  * @package  SOAP
  245.  * @author   Shane Caraveo <shane@php.net> Conversion to PEAR and updates
  246.  */
  247. class SOAP_Base extends SOAP_Base_Object
  248. {
  249.     var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema',
  250.                             'http://www.w3.org/1999/XMLSchema');
  251.     var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
  252.  
  253.     // load types into typemap array
  254.     var $_typemap = array(
  255.         'http://www.w3.org/2001/XMLSchema' => array(
  256.             'string' => 'string',
  257.             'boolean' => 'boolean',
  258.             'float' => FLOAT,
  259.             'double' => FLOAT,
  260.             'decimal' => FLOAT,
  261.             'duration' => 'integer',
  262.             'dateTime' => 'string',
  263.             'time' => 'string',
  264.             'date' => 'string',
  265.             'gYearMonth' => 'integer',
  266.             'gYear' => 'integer',
  267.             'gMonthDay' => 'integer',
  268.             'gDay' => 'integer',
  269.             'gMonth' => 'integer',
  270.             'hexBinary' => 'string',
  271.             'base64Binary' => 'string',
  272.             // derived datatypes
  273.             'normalizedString' => 'string',
  274.             'token' => 'string',
  275.             'language' => 'string',
  276.             'NMTOKEN' => 'string',
  277.             'NMTOKENS' => 'string',
  278.             'Name' => 'string',
  279.             'NCName' => 'string',
  280.             'ID' => 'string',
  281.             'IDREF' => 'string',
  282.             'IDREFS' => 'string',
  283.             'ENTITY' => 'string',
  284.             'ENTITIES' => 'string',
  285.             'integer' => 'integer',
  286.             'nonPositiveInteger' => 'integer',
  287.             'negativeInteger' => 'integer',
  288.             // longs (64bit ints) are not supported cross-platform.
  289.             'long' => 'string',
  290.             'int' => 'integer',
  291.             'short' => 'integer',
  292.             'byte' => 'string',
  293.             'nonNegativeInteger' => 'integer',
  294.             'unsignedLong' => 'integer',
  295.             'unsignedInt' => 'integer',
  296.             'unsignedShort' => 'integer',
  297.             'unsignedByte' => 'integer',
  298.             'positiveInteger'  => 'integer',
  299.             'anyType' => 'string',
  300.             'anyURI' => 'string',
  301.             'QName' => 'string'
  302.         ),
  303.         'http://www.w3.org/1999/XMLSchema' => array(
  304.             'i4' => 'integer',
  305.             'int' => 'integer',
  306.             'boolean' => 'boolean',
  307.             'string' => 'string',
  308.             'double' => FLOAT,
  309.             'float' => FLOAT,
  310.             'dateTime' => 'string',
  311.             'timeInstant' => 'string',
  312.             'base64Binary' => 'string',
  313.             'base64' => 'string',
  314.             'ur-type' => 'string'
  315.         ),
  316.         'http://schemas.xmlsoap.org/soap/encoding/' => array(
  317.             'base64' => 'string',
  318.             'array' => 'array',
  319.             'Array' => 'array',
  320.             'Struct' => 'array')
  321.     );
  322.  
  323.     /**
  324.      * Default class name to use for decoded response objects.
  325.      *
  326.      * @var string $_defaultObjectClassname
  327.      */
  328.     var $_defaultObjectClassname = 'stdClass';
  329.  
  330.     /**
  331.      * Hash with used namespaces.
  332.      *
  333.      * @array
  334.      */
  335.     var $_namespaces;
  336.  
  337.     /**
  338.      * The default namespace.
  339.      *
  340.      * @string
  341.      */
  342.     var $_namespace;
  343.  
  344.     var $_xmlEntities = array('&' => '&',
  345.                               '<' => '<',
  346.                               '>' => '>',
  347.                               "'" => ''',
  348.                               '"' => '"');
  349.  
  350.     var $_doconversion = false;
  351.  
  352.     var $_attachments = array();
  353.  
  354.     var $_wsdl = null;
  355.  
  356.     /**
  357.      * True if we use section 5 encoding, or false if this is literal.
  358.      *
  359.      * @var boolean $_section5
  360.      */
  361.     var $_section5 = true;
  362.  
  363.     // Handle type to class mapping.
  364.     var $_auto_translation = false;
  365.     var $_type_translation = array();
  366.  
  367.     /**
  368.      * Constructor.
  369.      *
  370.      * @see $debug_data, _debug()
  371.      *
  372.      * @param string $faultcode  Error code.
  373.      */
  374.     function SOAP_Base($faultcode = 'Client')
  375.     {
  376.         parent::SOAP_Base_Object($faultcode);
  377.         $this->_resetNamespaces();
  378.     }
  379.  
  380.     /**
  381.      * Sets the default namespace.
  382.      *
  383.      * @param string $namespace  The default namespace.
  384.      */
  385.     function setDefaultNamespace($namespace)
  386.     {
  387.         $this->_namespace = $namespace;
  388.     }
  389.  
  390.     function _resetNamespaces()
  391.     {
  392.         $this->_namespaces = array(
  393.             'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV',
  394.             'http://www.w3.org/2001/XMLSchema' => 'xsd',
  395.             'http://www.w3.org/2001/XMLSchema-instance' => 'xsi',
  396.             'http://schemas.xmlsoap.org/soap/encoding/' => 'SOAP-ENC');
  397.     }
  398.  
  399.     /**
  400.      * Sets the schema version used in the SOAP message.
  401.      *
  402.      * @access private
  403.      * @see $_XMLSchema
  404.      *
  405.      * @param string $schemaVersion  The schema version.
  406.      */
  407.     function _setSchemaVersion($schemaVersion)
  408.     {
  409.         if (!in_array($schemaVersion, $this->_XMLSchema)) {
  410.             return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion");
  411.         }
  412.         $this->_XMLSchemaVersion = $schemaVersion;
  413.         $tmpNS = array_flip($this->_namespaces);
  414.         $tmpNS['xsd'] = $this->_XMLSchemaVersion;
  415.         $tmpNS['xsi'] = $this->_XMLSchemaVersion . '-instance';
  416.         $this->_namespaces = array_flip($tmpNS);
  417.     }
  418.  
  419.     function _getNamespacePrefix($ns)
  420.     {
  421.         if ($this->_namespace && $ns == $this->_namespace) {
  422.             return '';
  423.         }
  424.         if (isset($this->_namespaces[$ns])) {
  425.             return $this->_namespaces[$ns];
  426.         }
  427.         $prefix = 'ns' . count($this->_namespaces);
  428.         $this->_namespaces[$ns] = $prefix;
  429.         return $prefix;
  430.     }
  431.  
  432.     function _getNamespaceForPrefix($prefix)
  433.     {
  434.         $flipped = array_flip($this->_namespaces);
  435.         if (isset($flipped[$prefix])) {
  436.             return $flipped[$prefix];
  437.         }
  438.         return null;
  439.     }
  440.  
  441.     function _isSoapValue(&$value)
  442.     {
  443.         return is_a($value, 'SOAP_Value');
  444.     }
  445.  
  446.     function _serializeValue(&$value, $name = '', $type = false,
  447.                              $elNamespace = null, $typeNamespace = null,
  448.                              $options = array(), $attributes = array(),
  449.                              $artype = '')
  450.     {
  451.         $namespaces = array();
  452.         $arrayType = $array_depth = $xmlout_value = null;
  453.         $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = '';
  454.         $xmlout_type = $xmlns = $ptype = $array_type_ns = '';
  455.  
  456.         if (!$name || is_numeric($name)) {
  457.             $name = 'item';
  458.         }
  459.  
  460.         if ($this->_wsdl) {
  461.             list($ptype, $arrayType, $array_type_ns, $array_depth)
  462.                 = $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
  463.         }
  464.  
  465.         if (!$arrayType) {
  466.             $arrayType = $artype;
  467.         }
  468.         if (!$ptype) {
  469.             $ptype = $this->_getType($value);
  470.         }
  471.         if (!$type) {
  472.             $type = $ptype;
  473.         }
  474.  
  475.         if (strcasecmp($ptype, 'Struct') == 0 ||
  476.             strcasecmp($type, 'Struct') == 0) {
  477.             // Struct
  478.             $vars = null;
  479.             if (is_object($value)) {
  480.                 $vars = get_object_vars($value);
  481.             } else {
  482.                 $vars = &$value;
  483.             }
  484.             if (is_array($vars)) {
  485.                 foreach (array_keys($vars) as $k) {
  486.                     // Hide private vars.
  487.                     if ($k[0] == '_') continue;
  488.                     if (is_object($vars[$k])) {
  489.                         if (is_a($vars[$k], 'SOAP_Value')) {
  490.                             $xmlout_value .= $vars[$k]->serialize($this);
  491.                         } else {
  492.                             // XXX get the members and serialize them instead
  493.                             // converting to an array is more overhead than we
  494.                             // should really do.
  495.                             $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5 ? null : $elNamespace);
  496.                         }
  497.                     } else {
  498.                         $xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace);
  499.                     }
  500.                 }
  501.             }
  502.         } elseif (strcasecmp($ptype, 'Array') == 0 ||
  503.                   strcasecmp($type, 'Array') == 0) {
  504.             // Array.
  505.             $typeNamespace = SOAP_SCHEMA_ENCODING;
  506.             $orig_type = $type;
  507.             $type = 'Array';
  508.             $numtypes = 0;
  509.             // XXX this will be slow on larger arrays.  Basically, it flattens
  510.             // arrays to allow us to serialize multi-dimensional arrays.  We
  511.             // only do this if arrayType is set, which will typically only
  512.             // happen if we are using WSDL
  513.             if (isset($options['flatten']) ||
  514.                 ($arrayType &&
  515.                  (strchr($arrayType, ',') || strstr($arrayType, '][')))) {
  516.                 $numtypes = $this->_multiArrayType($value, $arrayType,
  517.                                                    $ar_size, $xmlout_value);
  518.             }
  519.  
  520.             $array_type = $array_type_prefix = '';
  521.             if ($numtypes != 1) {
  522.                 $arrayTypeQName =& new QName($arrayType);
  523.                 $arrayType = $arrayTypeQName->name;
  524.                 $array_types = array();
  525.                 $array_val = null;
  526.  
  527.                 // Serialize each array element.
  528.                 $ar_size = count($value);
  529.                 foreach ($value as $array_val) {
  530.                     if ($this->_isSoapValue($array_val)) {
  531.                         $array_type = $array_val->type;
  532.                         $array_types[$array_type] = 1;
  533.                         $array_type_ns = $array_val->type_namespace;
  534.                         $xmlout_value .= $array_val->serialize($this);
  535.                     } else {
  536.                         $array_type = $this->_getType($array_val);
  537.                         $array_types[$array_type] = 1;
  538.                         $xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace);
  539.                     }
  540.                 }
  541.  
  542.                 $xmlout_offset = ' SOAP-ENC:offset="[0]"';
  543.                 if (!$arrayType) {
  544.                     $numtypes = count($array_types);
  545.                     if ($numtypes == 1) {
  546.                         $arrayType = $array_type;
  547.                     }
  548.                     // Using anyType is more interoperable.
  549.                     if ($array_type == 'Struct') {
  550.                         $array_type = '';
  551.                     } elseif ($array_type == 'Array') {
  552.                         $arrayType = 'anyType';
  553.                         $array_type_prefix = 'xsd';
  554.                     } else {
  555.                         if (!$arrayType) {
  556.                             $arrayType = $array_type;
  557.                         }
  558.                     }
  559.                 }
  560.             }
  561.             if (!$arrayType || $numtypes > 1) {
  562.                 // Should reference what schema we're using.
  563.                 $arrayType = 'xsd:anyType';
  564.             } else {
  565.                 if ($array_type_ns) {
  566.                     $array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
  567.                 } elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) {
  568.                     $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
  569.                 }
  570.                 if ($array_type_prefix) {
  571.                     $arrayType = $array_type_prefix . ':' . $arrayType;
  572.                 }
  573.             }
  574.  
  575.             $xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType;
  576.             if ($array_depth != null) {
  577.                 for ($i = 0; $i < $array_depth; $i++) {
  578.                     $xmlout_arrayType .= '[]';
  579.                 }
  580.             }
  581.             $xmlout_arrayType .= "[$ar_size]\"";
  582.         } elseif ($this->_isSoapValue($value)) {
  583.             $xmlout_value = $value->serialize($this);
  584.         } elseif ($type == 'string') {
  585.             $xmlout_value = htmlspecialchars($value);
  586.         } elseif ($type == 'rawstring') {
  587.             $xmlout_value =& $value;
  588.         } elseif ($type == 'boolean') {
  589.             $xmlout_value = $value ? 'true' : 'false';
  590.         } else {
  591.             $xmlout_value =& $value;
  592.         }
  593.  
  594.         // Add namespaces.
  595.         if ($elNamespace) {
  596.             $elPrefix = $this->_getNamespacePrefix($elNamespace);
  597.             if ($elPrefix) {
  598.                 $xmlout_name = "$elPrefix:$name";
  599.             } else {
  600.                 $xmlout_name = $name;
  601.             }
  602.         } else {
  603.             $xmlout_name = $name;
  604.         }
  605.  
  606.         if ($typeNamespace) {
  607.             $typePrefix = $this->_getNamespacePrefix($typeNamespace);
  608.             if ($typePrefix) {
  609.                 $xmlout_type = "$typePrefix:$type";
  610.             } else {
  611.                 $xmlout_type = $type;
  612.             }
  613.         } elseif ($type &&
  614.                   isset($this->_typemap[$this->_XMLSchemaVersion][$type])) {
  615.             $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
  616.             if ($typePrefix) {
  617.                 $xmlout_type = "$typePrefix:$type";
  618.             } else {
  619.                 $xmlout_type = $type;
  620.             }
  621.         }
  622.  
  623.         // Handle additional attributes.
  624.         $xml_attr = '';
  625.         if (count($attributes)) {
  626.             foreach ($attributes as $k => $v) {
  627.                 $kqn =& new QName($k);
  628.                 $vqn =& new QName($v);
  629.                 $xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"';
  630.             }
  631.         }
  632.  
  633.         // Store the attachment for mime encoding.
  634.         if (isset($options['attachment']) &&
  635.             !PEAR::isError($options['attachment'])) {
  636.             $this->_attachments[] = $options['attachment'];
  637.         }
  638.  
  639.         if ($this->_section5) {
  640.             if ($xmlout_type) {
  641.                 $xmlout_type = " xsi:type=\"$xmlout_type\"";
  642.             }
  643.             if (is_null($xmlout_value)) {
  644.                 $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
  645.                     "$xml_attr xsi:nil=\"true\"/>";
  646.             } else {
  647.                 $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
  648.                     "$xmlout_offset$xml_attr>$xmlout_value</$xmlout_name>";
  649.             }
  650.         } else {
  651.             if (is_null($xmlout_value)) {
  652.                 $xml = "\r\n<$xmlout_name$xmlns$xml_attr/>";
  653.             } else {
  654.                 $xml = "\r\n<$xmlout_name$xmlns$xml_attr>" .
  655.                     $xmlout_value . "</$xmlout_name>";
  656.             }
  657.         }
  658.  
  659.         return $xml;
  660.     }
  661.  
  662.     /**
  663.      * Converts a PHP type to a SOAP type.
  664.      *
  665.      * @access   private
  666.      *
  667.      * @param string $value  The value to inspect.
  668.      *
  669.      * @return string  The value's SOAP type.
  670.      */
  671.     function _getType(&$value)
  672.     {
  673.         global $SOAP_OBJECT_STRUCT, $SOAP_RAW_CONVERT;
  674.  
  675.         $type = gettype($value);
  676.         switch ($type) {
  677.         case 'object':
  678.             if (is_a($value, 'soap_value')) {
  679.                 $type = $value->type;
  680.             } else {
  681.                 $type = 'Struct';
  682.             }
  683.             break;
  684.  
  685.         case 'array':
  686.             // Hashes are always handled as structs.
  687.             if ($this->_isHash($value)) {
  688.                 $type = 'Struct';
  689.             } else {
  690.                 $ar_size = count($value);
  691.                 reset($value);
  692.                 $key1 = key($value);
  693.                 if ($ar_size > 0 && is_a($key1, 'SOAP_Value')) {
  694.                     // FIXME: for non-wsdl structs that are all the same type
  695.                     $key2 = key($value);
  696.                     if ($ar_size > 1 &&
  697.                         $this->_isSoapValue($key1) &&
  698.                         $this->_isSoapValue($key2) &&
  699.                         $key1->name != $key2->name) {
  700.                         // This is a struct, not an array.
  701.                         $type = 'Struct';
  702.                     } else {
  703.                         $type = 'Array';
  704.                     }
  705.                 } else {
  706.                     $type = 'Array';
  707.                 }
  708.             }
  709.             break;
  710.  
  711.         case 'integer':
  712.         case 'long':
  713.             $type = 'int';
  714.             break;
  715.  
  716.         case 'boolean':
  717.             break;
  718.  
  719.         case 'double':
  720.             // double is deprecated in PHP 4.2 and later.
  721.             $type = 'float';
  722.             break;
  723.  
  724.         case 'null':
  725.             $type = '';
  726.             break;
  727.  
  728.         case 'string':
  729.             if ($SOAP_RAW_CONVERT) {
  730.                 if (is_numeric($value)) {
  731.                     if (strstr($value, '.')) {
  732.                         $type = 'float';
  733.                     } else {
  734.                         $type = 'int';
  735.                     }
  736.                 } else {
  737.                     if (SOAP_Type_hexBinary::is_hexbin($value)) {
  738.                         $type = 'hexBinary';
  739.                     } else {
  740.                         if ($this->_isBase64($value)) {
  741.                             $type = 'base64Binary';
  742.                         } else {
  743.                             $dt =& new SOAP_Type_dateTime($value);
  744.                             if ($dt->toUnixtime() != -1) {
  745.                                 $type = 'dateTime';
  746.                             }
  747.                         }
  748.                     }
  749.                 }
  750.             }
  751.             break;
  752.  
  753.         default:
  754.             break;
  755.         }
  756.  
  757.         return $type;
  758.     }
  759.  
  760.     function _multiArrayType(&$value, &$type, &$size, &$xml)
  761.     {
  762.         $sz = count($value);
  763.         if (is_array($value)) {
  764.             // Seems we have a multi dimensional array, figure it out if we
  765.             // do.
  766.             $c = count($value);
  767.             for ($i = 0; $i < $c; $i++) {
  768.                 $this->_multiArrayType($value[$i], $type, $size, $xml);
  769.             }
  770.  
  771.             if ($size) {
  772.                 $size = $sz. ',' . $size;
  773.             } else {
  774.                 $size = $sz;
  775.             }
  776.  
  777.             return 1;
  778.         } else {
  779.             if (is_object($value)) {
  780.                 $type = $value->type;
  781.                 $xml .= $value->serialize($this);
  782.             } else {
  783.                 $type = $this->_getType($value);
  784.                 $xml .= $this->_serializeValue($value, 'item', $type);
  785.             }
  786.         }
  787.         $size = null;
  788.  
  789.         return 1;
  790.     }
  791.  
  792.     /**
  793.      * Returns whether a string is base64 encoded data.
  794.      *
  795.      * @param string $value  The string to check.
  796.      *
  797.      * @return boolean  True if the specified value seems to be base64 encoded.
  798.      */
  799.     function _isBase64(&$value)
  800.     {
  801.         $l = strlen($value);
  802.         if ($l) {
  803.             return $value[$l - 1] == '=' &&
  804.                 preg_match('/[A-Za-z=\/\+]+/', $value);
  805.         }
  806.         return false;
  807.     }
  808.  
  809.     /**
  810.      * Returns whether a type is a base64 type.
  811.      *
  812.      * @param string $type  A type name.
  813.      *
  814.      * @return boolean  True if the type name is a base64 type.
  815.      */
  816.     function _isBase64Type($type)
  817.     {
  818.         return $type == 'base64' || $type == 'base64Binary';
  819.     }
  820.  
  821.     /**
  822.      * Returns whether an array is a hash.
  823.      *
  824.      * @param array $a  An array to check.
  825.      *
  826.      * @return boolean  True if the specified array is a hash.
  827.      */
  828.     function _isHash(&$a)
  829.     {
  830.         // I really dislike having to loop through this in PHP code, really
  831.         // large arrays will be slow.  We need a C function to do this.
  832.         $it = 0;
  833.         foreach ($a as $k => $v) {
  834.             // Checking the type is faster than regexp.
  835.             if (is_int($k) || $this->_isSoapValue($v)) {
  836.                 return true;
  837.             }
  838.             // If someone has a large hash they should really be defining the
  839.             // type.
  840.             if ($it++ > 10) {
  841.              $this->_raiseSoapFault('Large associative array passed where a SOAP_Value was expected');
  842.                 return false;
  843.             }
  844.         }
  845.         return false;
  846.     }
  847.  
  848.     function _un_htmlentities($string)
  849.     {
  850.         $trans_tbl = get_html_translation_table(HTML_ENTITIES);
  851.         $trans_tbl = array_flip($trans_tbl);
  852.         return strtr($string, $trans_tbl);
  853.     }
  854.  
  855.     function &_decode(&$soapval)
  856.     {
  857.         global $SOAP_OBJECT_STRUCT;
  858.  
  859.         if (!$this->_isSoapValue($soapval)) {
  860.             return $soapval;
  861.         } elseif (is_array($soapval->value)) {
  862.             if ($SOAP_OBJECT_STRUCT && $soapval->type != 'Array') {
  863.                 $classname = $this->_defaultObjectClassname;
  864.                 if (isset($this->_type_translation[$soapval->tqn->fqn()])) {
  865.                     // This will force an error in PHP if the class does not
  866.                     // exist.
  867.                     $classname = $this->_type_translation[$soapval->tqn->fqn()];
  868.                 } elseif (isset($this->_type_translation[$soapval->type])) {
  869.                     // This will force an error in PHP if the class does not
  870.                     // exist.
  871.                     $classname = $this->_type_translation[$soapval->type];
  872.                 } elseif ($this->_auto_translation) {
  873.                     if (class_exists($soapval->type)) {
  874.                         $classname = $soapval->type;
  875.                     } elseif ($this->_wsdl) {
  876.                         $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace);
  877.                         if ($t && class_exists($t)) {
  878.                             $classname = $t;
  879.                         }
  880.                     }
  881.                 }
  882.                 $return =& new $classname;
  883.             } else {
  884.                 $return = array();
  885.             }
  886.  
  887.             $counter = 1;
  888.             $isstruct = !$SOAP_OBJECT_STRUCT || !is_array($return);
  889.             foreach ($soapval->value as $item) {
  890.                 if (is_object($return)) {
  891.                     if ($this->_wsdl) {
  892.                         // Get this child's WSDL information.
  893.                         // /$soapval->ns/$soapval->type/$item->ns/$item->name
  894.                         $child_type = $this->_wsdl->getComplexTypeChildType(
  895.                             $soapval->namespace,
  896.                             $soapval->name,
  897.                             $item->namespace,
  898.                             $item->name);
  899.                         if ($child_type) {
  900.                             $item->type = $child_type;
  901.                         }
  902.                     }
  903.                     if (!$isstruct || $item->type == 'Array') {
  904.                         if (isset($return->{$item->name}) &&
  905.                             is_object($return->{$item->name})) {
  906.                             $return->{$item->name} =& $this->_decode($item);
  907.                         } elseif (isset($return->{$item->name}) &&
  908.                                   is_array($return->{$item->name})) {
  909.                             $return->{$item->name}[] = $this->_decode($item);
  910.                         } elseif (is_array($return)) {
  911.                             $return[] =& $this->_decode($item);
  912.                         } else {
  913.                             $return->{$item->name} =& $this->_decode($item);
  914.                         }
  915.                     } elseif (isset($return->{$item->name})) {
  916.                         $isstruct = false;
  917.                         if (count(get_object_vars($return)) == 1) {
  918.                             $d =& $this->_decode($item);
  919.                             $return = array($return->{$item->name}, $d);
  920.                         } else {
  921.                             $d =& $this->_decode($item);
  922.                             $return->{$item->name} = array($return->{$item->name}, $d);
  923.                         }
  924.                     } else {
  925.                         $return->{$item->name} =& $this->_decode($item);
  926.                     }
  927.                     // Set the attributes as members in the class.
  928.                     if (method_exists($return, '__set_attribute')) {
  929.                         foreach ($soapval->attributes as $key => $value) {
  930.                             call_user_func_array(array(&$return,
  931.                                                        '__set_attribute'),
  932.                                                  array($key, $value));
  933.                         }
  934.                     }
  935.                 } else {
  936.                     if ($soapval->arrayType && $this->_isSoapValue($item)) {
  937.                         if ($this->_isBase64Type($item->type) &&
  938.                             !$this->_isBase64Type($soapval->arrayType)) {
  939.                             // Decode the value if we're losing the base64
  940.                             // type information.
  941.                             $item->value = base64_decode($item->value);
  942.                         }
  943.                         $item->type = $soapval->arrayType;
  944.                     }
  945.                     if (!$isstruct) {
  946.                         $return[] = $this->_decode($item);
  947.                     } elseif (isset($return[$item->name])) {
  948.                         $isstruct = false;
  949.                         $d =& $this->_decode($item);
  950.                         $return = array($return[$item->name], $d);
  951.                     } else {
  952.                         $return[$item->name] = $this->_decode($item);
  953.                     }
  954.                 }
  955.             }
  956.  
  957.             return $return;
  958.         }
  959.  
  960.         if ($soapval->type == 'boolean') {
  961.             if ($soapval->value != '0' &&
  962.                 strcasecmp($soapval->value, 'false') != 0) {
  963.                 $soapval->value = true;
  964.             } else {
  965.                 $soapval->value = false;
  966.             }
  967.         } elseif ($soapval->type &&
  968.                   isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) {
  969.             // If we can, set variable type.
  970.             settype($soapval->value,
  971.                     $this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]);
  972.         }
  973.  
  974.         if ($this->_isBase64Type($soapval->type)) {
  975.             $value = base64_decode($soapval->value);
  976.             return $value;
  977.         } else {
  978.             return $soapval->value;
  979.         }
  980.     }
  981.  
  982.     /**
  983.      * Creates the SOAP envelope with the SOAP envelop data.
  984.      *
  985.      * @param mixed $method
  986.      * @param array $headers
  987.      * @param string $encoding
  988.      * @param array $options
  989.      *
  990.      * @return string
  991.      */
  992.     function makeEnvelope(&$method, &$headers,
  993.                           $encoding = SOAP_DEFAULT_ENCODING,
  994.                           $options = array())
  995.     {
  996.         $smsg = $header_xml = $ns_string = '';
  997.  
  998.         if ($headers) {
  999.             $c = count($headers);
  1000.             for ($i = 0; $i < $c; $i++) {
  1001.                 $header_xml .= $headers[$i]->serialize($this);
  1002.             }
  1003.             $header_xml = "<SOAP-ENV:Header>\r\n$header_xml\r\n</SOAP-ENV:Header>\r\n";
  1004.         }
  1005.  
  1006.         if (!isset($options['input']) || $options['input'] == 'parse') {
  1007.             if (is_array($method)) {
  1008.                 $c = count($method);
  1009.                 for ($i = 0; $i < $c; $i++) {
  1010.                     $smsg .= $method[$i]->serialize($this);
  1011.                 }
  1012.             } else {
  1013.                 $smsg = $method->serialize($this);
  1014.             }
  1015.         } else {
  1016.             $smsg = $method;
  1017.         }
  1018.         $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n";
  1019.  
  1020.         foreach ($this->_namespaces as $k => $v) {
  1021.             $ns_string .= " xmlns:$v=\"$k\"\r\n";
  1022.         }
  1023.         if ($this->_namespace) {
  1024.             $ns_string .= " xmlns=\"{$this->_namespace}\"\r\n";
  1025.         }
  1026.  
  1027.         /* If 'use' == 'literal', we do not put in the encodingStyle.  This is
  1028.          * denoted by $this->_section5 being false.  'use' can be defined at a
  1029.          * more granular level than we are dealing with here, so this does not
  1030.          * work for all services. */
  1031.         $xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n".
  1032.             "<SOAP-ENV:Envelope $ns_string".
  1033.             ($this->_section5 ? ' SOAP-ENV:encodingStyle="' . SOAP_SCHEMA_ENCODING . '"' : '').
  1034.             ">\r\n".
  1035.             "$header_xml$body</SOAP-ENV:Envelope>\r\n";
  1036.  
  1037.         return $xml;
  1038.     }
  1039.  
  1040.     function _makeMimeMessage(&$xml, $encoding = SOAP_DEFAULT_ENCODING)
  1041.     {
  1042.         global $SOAP_options;
  1043.  
  1044.         if (!isset($SOAP_options['Mime'])) {
  1045.             return $this->_raiseSoapFault('Mime is not installed');
  1046.         }
  1047.  
  1048.         // Encode any attachments.
  1049.         // See http://www.w3.org/TR/SOAP-attachments
  1050.         // Now we have to mime encode the message.
  1051.         $params = array('content_type' => 'multipart/related; type=text/xml');
  1052.         $msg =& new Mail_mimePart('', $params);
  1053.  
  1054.         // Add the xml part.
  1055.         $params['content_type'] = 'text/xml';
  1056.         $params['charset'] = $encoding;
  1057.         $params['encoding'] = 'base64';
  1058.         $msg->addSubPart($xml, $params);
  1059.  
  1060.         // Add the attachements
  1061.         for ($i = 0, $c = count($this->_attachments); $i < $c; ++$i) {
  1062.             $attachment =& $this->_attachments[$i];
  1063.             $msg->addSubPart($attachment['body'], $attachment);
  1064.         }
  1065.  
  1066.         return $msg->encode();
  1067.     }
  1068.  
  1069.     // TODO: this needs to be used from the Transport system.
  1070.     function _makeDIMEMessage($xml)
  1071.     {
  1072.         global $SOAP_options;
  1073.  
  1074.         if (!isset($SOAP_options['DIME'])) {
  1075.             return $this->_raiseSoapFault('DIME is not installed');
  1076.         }
  1077.  
  1078.         // Encode any attachments.
  1079.         // See http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt
  1080.         // Now we have to DIME encode the message
  1081.         $dime =& new Net_DIME_Message();
  1082.         $msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI);
  1083.  
  1084.         // Add the attachments.
  1085.         $c = count($this->_attachments);
  1086.         for ($i = 0; $i < $c; $i++) {
  1087.             $attachment =& $this->_attachments[$i];
  1088.             $msg .= $dime->encodeData($attachment['body'],
  1089.                                       $attachment['content_type'],
  1090.                                       $attachment['cid'],
  1091.                                       NET_DIME_TYPE_MEDIA);
  1092.         }
  1093.         $msg .= $dime->endMessage();
  1094.  
  1095.         return $msg;
  1096.     }
  1097.  
  1098.     function _decodeMimeMessage(&$data, &$headers, &$attachments)
  1099.     {
  1100.         global $SOAP_options;
  1101.  
  1102.         if (!isset($SOAP_options['Mime'])) {
  1103.             $this->_raiseSoapFault('Mime Unsupported, install PEAR::Mail::Mime', '', '', 'Server');
  1104.             return;
  1105.         }
  1106.  
  1107.         $params['include_bodies'] = true;
  1108.         $params['decode_bodies']  = true;
  1109.         $params['decode_headers'] = true;
  1110.  
  1111.         // Lame thing to have to do for decoding.
  1112.         $decoder =& new Mail_mimeDecode($data);
  1113.         $structure = $decoder->decode($params);
  1114.  
  1115.         if (isset($structure->body)) {
  1116.             $data = $structure->body;
  1117.             $headers = $structure->headers;
  1118.  
  1119.             return;
  1120.         } elseif (isset($structure->parts)) {
  1121.             $data = $structure->parts[0]->body;
  1122.             $headers = array_merge($structure->headers,
  1123.                                    $structure->parts[0]->headers);
  1124.             if (count($structure->parts) > 1) {
  1125.                 $mime_parts = array_splice($structure->parts,1);
  1126.                 // Prepare the parts for the SOAP parser.
  1127.  
  1128.                 $c = count($mime_parts);
  1129.                 for ($i = 0; $i < $c; $i++) {
  1130.                     $p =& $mime_parts[$i];
  1131.                     if (isset($p->headers['content-location'])) {
  1132.                         // TODO: modify location per SwA note section 3
  1133.                         // http://www.w3.org/TR/SOAP-attachments
  1134.                         $attachments[$p->headers['content-location']] = $p->body;
  1135.                     } else {
  1136.                         $cid = 'cid:' . substr($p->headers['content-id'], 1, -1);
  1137.                         $attachments[$cid] = $p->body;
  1138.                     }
  1139.                 }
  1140.             }
  1141.  
  1142.             return;
  1143.         }
  1144.  
  1145.         $this->_raiseSoapFault('Mime parsing error', '', '', 'Server');
  1146.     }
  1147.  
  1148.     function _decodeDIMEMessage(&$data, &$headers, &$attachments)
  1149.     {
  1150.         global $SOAP_options;
  1151.  
  1152.         if (!isset($SOAP_options['DIME'])) {
  1153.             $this->_raiseSoapFault('DIME Unsupported, install PEAR::Net::DIME', '', '', 'Server');
  1154.             return;
  1155.         }
  1156.  
  1157.         // This SHOULD be moved to the transport layer, e.g. PHP itself should
  1158.         // handle parsing DIME ;)
  1159.         $dime =& new Net_DIME_Message();
  1160.         $err = $dime->decodeData($data);
  1161.         if (PEAR::isError($err)) {
  1162.             $this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server');
  1163.             return;
  1164.         }
  1165.         if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) {
  1166.             $this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server');
  1167.             return;
  1168.         }
  1169.  
  1170.         $data = $dime->parts[0]['data'];
  1171.         // Fake it for now.
  1172.         $headers['content-type'] = 'text/xml';
  1173.         $c = count($dime->parts);
  1174.         for ($i = 0; $i < $c; $i++) {
  1175.             $part =& $dime->parts[$i];
  1176.             // We need to handle URI's better.
  1177.             $id = strncmp($part['id'], 'cid:', 4)
  1178.                 ? 'cid:' . $part['id']
  1179.                 : $part['id'];
  1180.             $attachments[$id] = $part['data'];
  1181.         }
  1182.     }
  1183.  
  1184.     /**
  1185.      * @deprecated Use setTypeTranslation().
  1186.      */
  1187.     function __set_type_translation($type, $class = null)
  1188.     {
  1189.         $this->setTypeTranslation($type, $class);
  1190.     }
  1191.  
  1192.     /**
  1193.      * Explicitly sets the translation for a specific class.
  1194.      *
  1195.      * Auto translation works for all cases, but opens ANY class in the script
  1196.      * to be used as a data type, and may not be desireable.
  1197.      *
  1198.      * @param string $type   A SOAP type.
  1199.      * @param string $class  A PHP class name.
  1200.      */
  1201.     function setTypeTranslation($type, $class = null)
  1202.     {
  1203.         $tq =& new QName($type);
  1204.         if (!$class) {
  1205.             $class = $tq->name;
  1206.         }
  1207.         $this->_type_translation[$type]=$class;
  1208.     }
  1209.  
  1210. }
  1211.  
  1212. /**
  1213.  * Class used to handle QNAME values in XML.
  1214.  *
  1215.  * @access   public
  1216.  * @package  SOAP
  1217.  * @author   Shane Caraveo <shane@php.net> Conversion to PEAR and updates
  1218.  */
  1219. class QName
  1220. {
  1221.     var $name = '';
  1222.     var $ns = '';
  1223.     var $namespace='';
  1224.  
  1225.     function QName($name, $namespace = '')
  1226.     {
  1227.         if ($name && $name[0] == '{') {
  1228.             preg_match('/\{(.*?)\}(.*)/', $name, $m);
  1229.             $this->name = $m[2];
  1230.             $this->namespace = $m[1];
  1231.         } elseif (substr_count($name, ':') == 1) {
  1232.             $s = explode(':', $name);
  1233.             $s = array_reverse($s);
  1234.             $this->name = $s[0];
  1235.             $this->ns = $s[1];
  1236.             $this->namespace = $namespace;
  1237.         } else {
  1238.             $this->name = $name;
  1239.             $this->namespace = $namespace;
  1240.         }
  1241.  
  1242.         // A little more magic than should be in a qname.
  1243.         $p = strpos($this->name, '[');
  1244.         if ($p) {
  1245.             // TODO: Need to re-examine this logic later.
  1246.             // Chop off [].
  1247.             $this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2));
  1248.             $this->arrayInfo = substr($this->name, $p);
  1249.             $this->name = substr($this->name, 0, $p);
  1250.         }
  1251.     }
  1252.  
  1253.     function fqn()
  1254.     {
  1255.         if ($this->namespace) {
  1256.             return '{' . $this->namespace . '}' . $this->name;
  1257.         } elseif ($this->ns) {
  1258.             return $this->ns . ':' . $this->name;
  1259.         }
  1260.         return $this->name;
  1261.     }
  1262.  
  1263. }
  1264.